/*===============================================================
 *  Copyright (C) 2020 miHoYo All rights reserved.
 *
 * Author: yu.guo@mihoyo.com
 * Created: 2020-12-21 11:58
 * Last modified: 2020/12/21 18:29
 * File: main.cpp
 * Desc:
 * 1.由于pthread库不是Linux系统默认的库，连接时需要使用库libpthread.a,所以在使用pthread_create创建线程时，在编译中要加-lpthread参数:)
 * 2. 线程通过启动例程中返回终止，清理程序不会调用。
 * ==============================================================*/

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

void cleanup(void* arg)
{
    printf("clean up : %s\n", (char*) arg);
}

void* thr_fn1(void* arg)
{
    printf("thread 1 start\n");
    pthread_cleanup_push(cleanup, (void*)"thread 1 first handler");
    pthread_cleanup_push(cleanup, (void*)"thread 1 second handler");
    printf("thread 1 push complete\n");

    if (arg)
        return ((void*) 1);
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);

    return ((void*)1);
}

void* thr_fn2(void* arg)
{
    printf("thread 2 start\n");
    pthread_cleanup_push(cleanup, (void*)"thread 2 first handler");
    pthread_cleanup_push(cleanup, (void*)"thread 2 second handler");
    printf("thread 2 push complete\n");
    if (arg)
        pthread_exit((void*)2);
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);
    printf("thread 2 eixting\n");
    pthread_exit((void*)2);
}

int main(void)
{
    int err;
    pthread_t tid1, tid2;
    void* tret;

    err = pthread_create(&tid1, NULL, thr_fn1, NULL);
    if (err != 0)
    {
        printf("create thread failed.\n");
        exit(1);
    }
    err = pthread_create(&tid2, NULL, thr_fn2, NULL);
    if (err != 0)
    {
        printf("create thread failed.\n");
        exit(1);
    }

    err = pthread_join(tid1, &tret);
    if (err != 0)
    {
        printf("can not join with thread 1\n");
        exit(1);
    }
    printf("thread 1 exit code %ld \n", (long) tret);

    err = pthread_join(tid2, &tret);
    if (err != 0)
    {
        printf("can not join with thread 2\n");
        exit(1);
    }
    printf("thread 2 exit code %ld \n", (long) tret);

    exit(0);
}
